package controllers

import (
	"fmt"
	"ginstudydemo.com/main/models"
	"ginstudydemo.com/main/service"
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/copier"
	"strconv"
	"strings"
)

type IUserController interface {
	GetUserInfoByToken()
	AddUser()
	GetInfo()
	GetList()
	EditUser()
	//------以下旧接口废弃
	AddUsers()
	SaveUser()
	DelUsers()
}

type UserController struct{}

func NewUserController() *UserController {
	return &UserController{}
}

// GetUserInfoByToken 根据token获取当前登录用户信息
func (u UserController) GetUserInfoByToken(c *gin.Context) {
	claims, exists := c.Get("claims")
	if !exists {
		service.ReturnErr(c, "9999", "无法获取token信息")
		return
	}

	// 现在可以使用 claims 执行相关操作
	myClaims := claims.(*service.MyClaims)
	fmt.Println("------------")
	fmt.Println(myClaims.UserInfo.UserID)

	// strconv.FormatUint 是一个用于将无符号整数（uint64 类型）格式化为字符串
	idStr := strconv.FormatUint(myClaims.UserInfo.UserID, 10) // 第二个参数10表示使用十进制格式

	// 根据 myClaims.UserID 或其他字段从数据库获取用户信息并返回
	sysuser, modelErr := models.GetUserInfoById(idStr)
	if !(modelErr == nil) {
		service.ReturnErr(c, "9999", modelErr.Error())
		c.Abort()
		return
	}

	var meRes models.SysUserUsersMeRes
	cpErr := copier.Copy(&meRes, &sysuser)
	if cpErr != nil {
		service.ReturnErr(c, "9999", "密码不正确")
		c.Abort()
		return
	}
	// strings.Split 函数用于将字符串分割成多个子字符串，并返回一个字符串切片
	meRes.Roles = strings.Split(myClaims.UserInfo.Roles, ",")
	//根据角色取回权限列表
	sPerms, PermsErr := service.NewAuthService().GetPermsFromRedis(myClaims.UserInfo.Roles)
	if PermsErr != nil {
		service.ReturnErr(c, "9999", PermsErr.Error())
		c.Abort()
		return
	}
	meRes.Perms = sPerms
	service.ReturnSuccess[models.SysUserUsersMeRes](c, "2000", "ok", meRes)
}

// GetUserFormInfoById 根据id获取用户表单数据
func (u UserController) GetUserFormInfoById(c *gin.Context) {
	userId := c.Param("userId")

	userFomrS, modelErr := models.GetUserFormInfoById(userId)
	if !(modelErr == nil) {
		service.ReturnErr(c, "9999", modelErr.Error())
		c.Abort()
		return
	}
	var userFormRes models.SysUserUsersFormRes
	cpErr := copier.Copy(&userFormRes, &userFomrS)
	if cpErr != nil {
		service.ReturnErr(c, "9999", cpErr.Error())
		c.Abort()
		return
	}
	//获取角色ids
	roleIds, roleIdsErr := models.GetRoleIds(strconv.FormatInt(userFormRes.ID, 10))
	if !(roleIdsErr == nil) {
		service.ReturnErr(c, "9999", roleIdsErr.Error())
		c.Abort()
		return
	}
	userFormRes.RoleIDS = *roleIds
	service.ReturnSuccess[models.SysUserUsersFormRes](c, "2000", "ok", userFormRes)
}

// GetUserPageList 获取用户分页列表
func (u UserController) GetUserPageList(c *gin.Context) {
	var query models.SysUserUsersPageListParams
	var pagination models.PaginationParams
	// 获取查询参数（除分页参数）
	if err := c.ShouldBindQuery(&query); err != nil {
		service.ReturnErr(c, "9999", err.Error())
		c.Abort() // 终止后续处理
		return    // 确保不会继续执行后续代码
	}

	// 获取分页参数
	if qErr := c.ShouldBindQuery(&pagination); qErr != nil {
		service.ReturnErr(c, "9999", qErr.Error())
		c.Abort() // 终止后续处理
		return    // 确保不会继续执行后续代码
	}

	data, count, pageNum, pageSize, modelErr := models.GetUserPageList(query, pagination)

	if !(modelErr == nil) {
		service.ReturnErr(c, "9999", modelErr.Error())
		c.Abort()
		return
	}

	service.ReturnSuccess[models.SysUserUsersPageListRes](c, "2000", "ok", models.SysUserUsersPageListRes{
		Total:    count,
		PageSize: pageSize,
		PageNum:  pageNum,
		List:     data,
	})

}

// AddUser 新增后台系统用户
func (u UserController) AddUser(c *gin.Context) {
	//使用数据表结构体获取参数
	param := &models.SysUserAddParams{}
	// 把结构体指针传入BindJSON，这样param的值才能同步修改
	cErr := c.BindJSON(param)
	if !(cErr == nil) {
		service.ReturnErr(c, "9999", cErr.Error())
		c.Abort()
		return
	}
	//TODO：表单数据验证 1.用户名和手机号的格式 、2.用户名手机号是否唯一

	//TODO：这部分后期改到修改密码部分：对密码进行加密
	//hasedPassword, bcryptErr := bcrypt.GenerateFromPassword([]byte((*param).Password), bcrypt.DefaultCost)
	//if bcryptErr != nil {
	//	service.ReturnErr(c, "5000", bcryptErr)
	//	c.Abort()
	//	return
	//}
	//// 加密后的密码同步到用户信息中
	//(*param).Password = string(hasedPassword)
	fmt.Println("=======")
	fmt.Println(*param)
	fmt.Println("=======")
	userId, modelErr := models.AddUser(*param)
	if !(modelErr == nil) {
		service.ReturnErr(c, "9999", modelErr.Error())
		c.Abort()
		return
	}
	// 插入用户对应的角色数据(此方法插入之前先清空之前用户对应的角色，所以也适应修改)
	insertErr := models.InsertUserRoles(userId, param.RoleIDS)
	if !(insertErr == nil) {
		service.ReturnErr(c, "9999", insertErr.Error())
		c.Abort() // 终止后续处理
		return    // 确保不会继续执行后续代码
	}

	service.ReturnSuccess[int64](c, "2000", "ok", userId)

}

// EditUser 修改后台系统用户
func (u UserController) EditUser(c *gin.Context) {

	userId := c.Param("userId")

	//使用数据表结构体获取参数
	param := &models.SysUserEditParams{}
	// 把结构体指针传入BindJSON，这样param的值才能同步修改
	cErr := c.BindJSON(param)
	if !(cErr == nil) {
		service.ReturnErr(c, "9999", cErr.Error())
		c.Abort()
		return
	}

	//TODO：表单数据验证 1.用户名和手机号的格式 、2.用户名手机号是否唯一

	//TODO：这部分后期改到修改密码部分：对密码进行加密
	//hasedPassword, bcryptErr := bcrypt.GenerateFromPassword([]byte((*param).Password), bcrypt.DefaultCost)
	//if bcryptErr != nil {
	//	service.ReturnErr(c, "5000", bcryptErr)
	//	c.Abort()
	//	return
	//}
	//// 加密后的密码同步到用户信息中
	//(*param).Password = string(hasedPassword)
	fmt.Println("=======")
	fmt.Println(*param)
	fmt.Println("=======")
	modelErr := models.EditUser(*param, userId)
	if !(modelErr == nil) {
		service.ReturnErr(c, "9999", modelErr.Error())
		c.Abort()
		return
	}

	// 插入用户对应的角色数据(此方法插入之前先清空之前用户对应的角色，所以也适应修改)
	userIdInt, _ := strconv.ParseInt(userId, 10, 64)
	insertErr := models.InsertUserRoles(userIdInt, param.RoleIDS)
	if !(insertErr == nil) {
		service.ReturnErr(c, "9999", insertErr.Error())
		c.Abort() // 终止后续处理
		return    // 确保不会继续执行后续代码
	}
	service.ReturnSuccess[string](c, "2000", "ok", userId)

}

// DelUsers 批量删除
func (u UserController) DelUsers(c *gin.Context) {

	userIds := c.Param("ids")

	if userIds == "" {
		service.ReturnErr(c, "9999", "error:ids为空")
		c.Abort() // 终止后续处理
		return    // 确保不会继续执行后续代码
	}

	//if err := c.ShouldBindJSON(&idsRequest); err != nil {
	//	service.ReturnErr(c, "9999", "error:系统错误#"+err.Error())
	//	c.Abort() // 终止后续处理
	//	return    // 确保不会继续执行后续代码
	//}
	//// 将 ID 数组转换为 []SysUser 类型的切片
	//var users []models.SysUser
	//for _, id := range idsRequest.Ids {
	//	users = append(users, models.SysUser{Id: id})
	//}
	modelErr := models.DelUsersSoft(userIds)
	if !(modelErr == nil) {
		service.ReturnErr(c, "9999", modelErr.Error())
		c.Abort() // 终止后续处理
		return    // 确保不会继续执行后续代码
	}
	service.ReturnSuccess(c, "2000", "ok", struct{}{})
}

// ResetPassword 重置用户密码
func (u UserController) ResetPassword(c *gin.Context) {
	userId := c.Param("userId")
	var query models.SysUserPassword
	if err := c.ShouldBindQuery(&query); err != nil {
		service.ReturnErr(c, "9999", err.Error())
		c.Abort() // 终止后续处理
		return    // 确保不会继续执行后续代码
	}

	modelErr := models.EditPassword(query, userId)
	if !(modelErr == nil) {
		service.ReturnErr(c, "9999", modelErr.Error())
		c.Abort() // 终止后续处理
		return    // 确保不会继续执行后续代码
	}
	service.ReturnSuccess(c, "2000", "ok", struct{}{})

}

// EditUserStatus 修改用户状态
func (u UserController) EditUserStatus(c *gin.Context) {
	userId := c.Param("userId")
	var query models.SysUserStatus
	if err := c.ShouldBindQuery(&query); err != nil {
		service.ReturnErr(c, "9999", err.Error())
		c.Abort() // 终止后续处理
		return    // 确保不会继续执行后续代码
	}

	modelErr := models.EditStatus(query, userId)
	if !(modelErr == nil) {
		service.ReturnErr(c, "9999", modelErr.Error())
		c.Abort() // 终止后续处理
		return    // 确保不会继续执行后续代码
	}
	service.ReturnSuccess(c, "2000", "ok", struct{}{})
}

// GetUserProfile 获取个人中心用户信息
func (u UserController) GetUserProfile(c *gin.Context) {
	userId := c.Param("userId")

	profile, modelErr := models.GetUserProfile(userId)
	if !(modelErr == nil) {
		service.ReturnErr(c, "9999", modelErr.Error())
		c.Abort() // 终止后续处理
		return    // 确保不会继续执行后续代码
	}
	service.ReturnSuccess[models.UserProfile](c, "2000", "ok", *profile)
}

// EditUserProfile 修改个人中心用户信息
func (u UserController) EditUserProfile(c *gin.Context) {
	userId := c.Param("userId")

	//使用数据表结构体获取参数
	param := &models.UserProfile{}
	// 把结构体指针传入BindJSON，这样param的值才能同步修改
	cErr := c.BindJSON(param)
	if !(cErr == nil) {
		service.ReturnErr(c, "9999", cErr.Error())
		c.Abort()
		return
	}
	modelErr := models.EditUserProfile(param, userId)
	if !(modelErr == nil) {
		service.ReturnErr(c, "9999", modelErr.Error())
		c.Abort() // 终止后续处理
		return    // 确保不会继续执行后续代码
	}
	service.ReturnSuccess(c, "2000", "ok", struct{}{})
}

// ----以下旧代码-----------

// AddUsers 批量添加用户
func (u UserController) AddUsers(c *gin.Context) {
	//使用数据表结构体获取参数
	param := &[]models.SysUser{}
	// 把结构体指针传入BindJSON，这样param的值才能同步修改
	err := c.BindJSON(param)

	if !(err == nil) {
		service.ReturnErr(c, "9999", err.Error())
		c.Abort() // 终止后续处理
		return    // 确保不会继续执行后续代码
	}

	//fmt.Println(param)
	insertIds, insertErr := models.AddUsers(param)
	if !(insertErr == nil) {
		service.ReturnErr(c, "9999", insertErr.Error())
		c.Abort() // 终止后续处理
		return    // 确保不会继续执行后续代码
	}

	service.ReturnSuccess[[]uint64](c, "2000", "ok", insertIds)

}

// SaveUser 更新用户所有数据
func (u UserController) SaveUser(c *gin.Context) {
	//使用数据表结构体获取参数
	param := &models.SysUser{}
	// 把结构体指针传入BindJSON，这样param的值才能同步修改
	err := c.BindJSON(param)

	if !(err == nil) {
		service.ReturnErr(c, "9999", err.Error())
		c.Abort() // 终止后续处理
		return    // 确保不会继续执行后续代码
	}

	//fmt.Println(param)
	insertId, insertErr := models.SaveUser(param)
	if !(insertErr == nil) {
		service.ReturnErr(c, "9999", insertErr.Error())
		c.Abort() // 终止后续处理
		return    // 确保不会继续执行后续代码
	}

	service.ReturnSuccess[uint64](c, "2000", "ok", insertId)

}
